const validate = new Object()
validate.install = function (Vue) {
  const resetError = (el) => {
    el.className = el.className.replace('input-error', '').trim()
    if (el.parentNode) {
      const ErrorNode = el.parentNode.querySelector('.error-tips')
      if (ErrorNode) {
        el.parentNode.removeChild(ErrorNode)
      }
    }
  }
  const validateError = (el, errorMsg) => {
    if (Array.prototype.includes.call(el.classList, 'input-error')) {
      //如果当前组件里已经有了错误提示信息，什么也不做
      return
    } else {
      const errorNode = document.createElement('div')
      errorNode.className = 'error-tips'
      errorNode.textContent =
        typeof errorMsg === 'function' ? errorMsg() : errorMsg
      if (el.parentNode) {
        // 在当前input 元素后追加一个p元素，内容为错误提示
        el.parentNode.appendChild(errorNode)
      }
      // 在当前input 元素上添加一个input-error类名
      el.className += ' input-error'
    }
  }
  Vue.directive('validate', {
    inserted(el, binding) {
      const target =
        el instanceof HTMLInputElement ? el : el.querySelector('input')
      el.addEventListener('keyup', function () {
        resetError(target)
        for (const rule of binding.value) {
          // 分别获取到自己定义的校验规则并执行
          const { msg, required, reg, validator } = rule
          if (!required && !target.value) {
            break
          }
          if (!!required && !target.value && !target.disabled) {
            validateError(target, msg)
            break
          }
          if (reg && !reg.test(target.value) && !target.disabled) {
            validateError(target, msg)
            break
          }
          if (
            validator &&
            typeof validator === 'function' &&
            !validator(target.value) &&
            !target.disabled
          ) {
            validateError(target, msg)
            break
          }
        }
      })
      el.addEventListener('blur', function () {
        resetError(target)
        for (const rule of binding.value) {
          // 分别获取到自己定义的校验规则并执行
          const { msg, required, reg, validator } = rule
          if (!required && !target.value) {
            break
          }
          if (!!required && !target.value && !target.disabled) {
            validateError(target, msg)
            break
          }
          if (reg && !reg.test(target.value) && !target.disabled) {
            validateError(target, msg)
            break
          }
          if (
            validator &&
            !typeof validator === 'function' &&
            !validator(target.value) &&
            !target.disabled
          ) {
            validateError(target, msg)
            break
          }
        }
      })
    }, // end bind
    update(el, binding, vnode, oldVnode) {
      const target =
        el instanceof HTMLInputElement ? el : el.querySelector('input')
      if (vnode.data.model.value !== oldVnode.data.model.value) {
        resetError(target)
      }
    },
  })
}

export default validate
